package org.casaca.checkbackup.core.data;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.util.List;

import org.casaca.checkbackup.core.exception.RootFolderException;
import org.casaca.checkbackup.core.util.SortedList;


public class Folder extends SystemElement{
	
	private List<SystemElement> children;
	private boolean childrenFlag;
	private BigInteger size;
	private long filesInFolder;
	private long filesInSubfolders;
	
	public static Folder createRootFolder(String path) throws RootFolderException {
		try {
			Constructor<Folder> constructor = Folder.class.getDeclaredConstructor(String.class);
			Folder folder = constructor.newInstance(path);
			return folder;
		} catch (SecurityException e) {
			throw new RootFolderException(e);
		} catch (NoSuchMethodException e) {
			throw new RootFolderException(e);
		} catch (IllegalArgumentException e) {
			throw new RootFolderException(e);
		} catch (InstantiationException e) {
			throw new RootFolderException(e);
		} catch (IllegalAccessException e) {
			throw new RootFolderException(e);
		} catch (InvocationTargetException e) {
			throw new RootFolderException(e);
		}
	}

	public Folder(Folder parent, String name) {
		super(parent, name);
		
		this.children = new SortedList<SystemElement>();
		this.childrenFlag = true;
		this.size = BigInteger.ZERO;
		this.filesInFolder = this.filesInSubfolders = 0;
	}
	
	private Folder(String path){
		super(path);
		this.children = new SortedList<SystemElement>();
		this.childrenFlag = true;
		this.size = BigInteger.ZERO;
		this.filesInFolder = this.filesInSubfolders = 0;
	}
	
	public List<SystemElement> getChildren(){
		return this.children;
	}
	
	public long getFilesInFolder(){
		if(childrenFlag){
			this.filesInFolder=0;
			for (SystemElement systemElement : this.children) {
				if(systemElement instanceof File)
					this.filesInFolder++;
			}
		}
		
		return this.filesInFolder;
	}
	
	public long getFilesIncludingSubfolders(){
		if(childrenFlag){
			this.filesInSubfolders = 0;
			for (SystemElement systemElement : this.children) {
				if(systemElement instanceof File){
					this.filesInSubfolders++;
				}
				else if(systemElement instanceof Folder){
					this.filesInSubfolders+=((Folder)systemElement).getFilesIncludingSubfolders();
				}
			}
		}
		
		return this.filesInSubfolders;
	}
	
	public SystemElement search(String path){
		return null;
	}

	@Override
	public BigInteger getSize() {
		if(childrenFlag){
			BigInteger size = BigInteger.ZERO;
			for (SystemElement se : this.children) {
				size = size.add(se.getSize());
			}
			this.size = size;
		}
		
		return this.size;
	}

	@Override
	public void setSize(BigInteger size) {
		throw new IllegalStateException("This method cannot be used for folders");
	}

	@Override
	public int compareTo(SystemElement o) {
		if(o instanceof File)
			return -1;
		else
			return this.getName().compareTo(o.getName());
	}
}